﻿using Fetion.Model;
using ProtoBuf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using System.ComponentModel;
using System.Diagnostics;
namespace Fetion.Core
{
   public  class ProtocolEntity 
        {
		public int packageSize = -1;
		public int ver = -1;
		public int userId = -1;
		public int cmd = -1;
		public int seq = -1;
		public int offset = -1;
		public int format = -1;
		public int zipFlag = -1;
		public int ct = -1;
		public int cv = -1;
		public byte[] opt;
		public int bodyLength = -1;
		public byte[] body;
		}
	
   public  class FetionFormatPackage:Package,IMessage
    {
       private const int defaultHeadLength = 25;
        public override byte[] GetMessageData(IMessage e)
        {
            return new byte[0];
        }
        private void WriteMS(MemoryStream ms, byte[] buffer, int length)
        {
            int offset = (int)ms.Position;
            ms.Write(buffer, offset, length);
        }
        private ProtocolEntity GetProtocalEntity(MemoryStream ms)
        {
            byte[] buffer = new byte[4];
            ProtocolEntity pe = new ProtocolEntity();
            ms.Read(buffer, 0, 2);
            pe.packageSize = BitConverter.ToInt16(buffer, 0);
            pe.ver = ms.ReadByte();
            ms.Read(buffer, 0, 4);
            pe.userId = BitConverter.ToInt32(buffer, 0);
            ms.Read(buffer, 0, 4);
            pe.cmd = BitConverter.ToInt32(buffer, 0);
            ms.Read(buffer, 0, 2);
            pe.seq = BitConverter.ToInt16(buffer, 0);
            pe.offset = ms.ReadByte();
            pe.format = ms.ReadByte();
            pe.zipFlag = ms.ReadByte();
            ms.Read(buffer, 0, 2);
            pe.ct = BitConverter.ToInt16(buffer, 0);
            ms.Read(buffer, 0, 2);
            pe.cv = BitConverter.ToInt16(buffer, 0);
            ms.Position = ms.Position + 1;//跳过空位

            if (pe.offset > defaultHeadLength)//可扩展包头不为空
            {
                pe.opt = new byte[pe.offset - defaultHeadLength];
                ms.Read(pe.opt, 0, pe.opt.Length);
            }
            pe.bodyLength = pe.packageSize - pe.offset;
            pe.body = new byte[pe.bodyLength];
            ms.Read(pe.body, 0, pe.bodyLength);
            return pe;
        }
        public override void Import(byte[] data, int start, int count,EventHandler<ClientAsyncCompletedEventArgs<object>> handle)
        {
            MemoryStream ms=new MemoryStream (data);
            while (ms.ReadByte() != 0)
            {
                ms.Position--;
                ProtocolEntity pe = GetProtocalEntity(ms);
                Stream body = new MemoryStream(pe.body);
                if (pe.zipFlag == 2)//需要解密
                { 

                }
                if (pe.zipFlag == 1)//需要解压
                {
                    body = new GZipInputStream(body);
                }
                HandleCmd(pe, body);

            }//while

        }

       /// <summary>
       /// 处理命令字逻辑
       /// </summary>
       /// <param name="pe"></param>
       /// <param name="body"></param>
        private void HandleCmd(ProtocolEntity pe,Stream body)
        {
            EnumCMD cmd = (EnumCMD)pe.cmd;
            if (pe.format == 128)//请求响应结果
            {
                #region 请求响应结果
                switch (cmd)
                {
                    case EnumCMD.Reg2V5RspArgs:
                        Reg2V5RspArgs model = Serializer.Deserialize<Reg2V5RspArgs>(body);
                        Request<Reg2V5RspArgs> req = TcpChannel.GetRequestBySeqId<Reg2V5RspArgs>(pe.seq);
                        if (req.ResHandle != null)
                        {
                            req.ResHandle(model);
                        }
                        break;

                    default:
                        break;
                }
                #endregion
            }
            else if(pe.format==1)//服务器推送消息
            {
                #region 服务器推送信息
                switch (cmd)
                {
                    case EnumCMD.NotifyCollectionArgs01:
                        NotifyCollectionArgs01 modelNotifyCollectionArgs01 = Serializer.Deserialize<NotifyCollectionArgs01>(body);
                        if (modelNotifyCollectionArgs01.type == "ContactList")
                        {
                            Debug.WriteLine("联系人状态通知");
                        }
                        else if (modelNotifyCollectionArgs01.type == "SyncUserInfo")
                        {
                            Debug.WriteLine("个人信息同步通知");
                        }
                        else if (modelNotifyCollectionArgs01.type == "Presence")
                        {
                            Debug.WriteLine("联系人状态通知");
                        }
                        break;
                    default:
                        break;
                }
                #endregion
            }
            else 
            {
                Debug.WriteLine("未识别的消息类型");
            }
        }
        public void Save(BufferWriter writer)
        {
            throw new NotImplementedException();
        }

        public void Load(BufferReader reader)
        {
            throw new NotImplementedException();
        }


        public byte[] GetBuffer()
        {
            throw new NotImplementedException();
        }
    }
}
